﻿/******************************************************************************
 * 【本类功能概述】                                 					      *
 *  版权所有（C）2017-20XX                                                    *
 *  保留所有权利。                                                            *
 ******************************************************************************
 *  作者 : <hughjk>
 *  创建时间:2020年11月6日 18:27:47
 *  文件描述:UDP模版
 *****************************************************************************/

using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using Util;
using UnityEngine;
using System;

public class NetUdpMgr : MonoBehaviour
{
    private void Update()
    {
        if (NetUdp.Instance.IsInit)
        {
            if (NetUdp.Instance.ReceiveHandler.Count > 0)
            {
                while (NetUdp.Instance.ReceiveHandler.Count > 0)
                {
                    NetUdp.Instance.SnedEve.toInvoke(NetUdp.Instance.ReceiveHandler[0]);
                    NetUdp.Instance.ReceiveHandler.RemoveAt(0);
                }
            }
        }
    }
}

public class NetUdp : Singleton<NetUdp>
{
    public Action<string> SnedEve;

    private Socket udpSendSocket = null;
    private Socket udpReceiveSocket = null;
    public int port = 9876;
    public List<string> ReceiveHandler = new List<string>();//接收信息后的回调

    public bool IsServer { set; get; }//是不是服务器
    private EndPoint ip;
    public bool IsInit = false;

    public NetUdp()
    {
        udpSendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        udpReceiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        ip = new IPEndPoint(IPAddress.Broadcast, port);
    }

    /// <summary>
    /// 创建UDPSocket
    /// </summary>
    /// <param name="port"></param>
    public void Init()
    {
#if !UNITY_EDITOR //不是编辑器环境下要重写真实文件路径的文件
        IsInit = true;
        StartReceive();
#endif
    }

    /// <summary>
    /// 发送请求服务器广播
    /// </summary>
    /// <param name="port"></param>
    public void SendMessage(string message)
    {
        byte[] data = Encoding.UTF8.GetBytes(message);
        udpSendSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
        udpSendSocket.SendTo(data, ip);
    }

    private Thread receiveThread = null;

    /// <summary>
    /// 开始接受消息
    /// </summary>
    public void StartReceive()
    {
        debug.log("开始接收消息");
        receiveThread = new Thread(ReceiveMessage);
        receiveThread.IsBackground = true;
        receiveThread.Start();
    }

    /// <summary>
    /// 客户端接收信息
    /// </summary>
    /// <returns></returns>
    private void ReceiveMessage()
    {
        EndPoint remote = new IPEndPoint(IPAddress.Any, port);
        udpReceiveSocket.Bind(remote);
        while (true)
        {
            try
            {
                byte[] data = new byte[2048];
                int length = udpReceiveSocket.ReceiveFrom(data, ref remote);
                string s = Encoding.UTF8.GetString(data, 0, length);
                ReceiveHandler.Add(s);
            }
            catch (ThreadAbortException ex)
            {
                //不进行操作
            }
            catch (System.Exception e)
            {
                debug.log("接收信息错误，错误信息：  " + e.ToString());
                UdpSocketQuit();
            }
            Thread.Sleep(100);//三秒接收一次
        }
    }

    /// <summary>
    /// 点击加入加入房间按钮时，断开UDP的Socket
    /// </summary>
    public void UdpSocketQuit()
    {
        //最后关闭socket

        if (receiveThread != null)
        {
            receiveThread.Interrupt();
            receiveThread.Abort();
            receiveThread = null;
        }
        if (udpReceiveSocket != null)
        {
            udpReceiveSocket.Close();
            udpReceiveSocket = null;
        }
        if (udpSendSocket != null)
        {
            udpSendSocket.Close();
            udpSendSocket = null;
        }
        debug.log("断开连接");
    }
}

//public class UiScript : MonoBehaviour
//{
//    NetUdp net;
//    private void Awake()
//    {
//        net = new NetUdp();
//        net.StartReceive();
//    }
//    public Text input;
//    public Text Out;
//    public void Send()
//    {
//        net.SendMessage(input.text);
//    }
//
//    private void Update()
//    {
//        while (net.ReceiveHandler.Count > 0)
//        {
//            Out.text = net.ReceiveHandler[0] + "\n" + Out.text;
//            net.ReceiveHandler.RemoveAt(0);
//        }
//    }
//    private void OnApplicationQuit()
//    {
//        net.UdpSocketQuit();
//    }
//}